<template>
	<div class="count-to-wrapper">
		<slot name="left"/>
			<p class="content-outer">
				<ICountUp :class="['count-to-count-text', countClass]" :delay="delay" :endVal="end" :options="options" @ready="onReady"/>
			</p>
		<slot name="right"/>
	</div>
</template>

<script>
import ICountUp from 'vue-countup-v2'
export default {
	name: 'CountTo',
	components: {
		ICountUp
	},
	props: {
		/**
		 * @description 结束值，即动画结束后显示的数值
		 */
		end: {
			type: Number,
			required: true
		},
		/**
		 * @description 动画延迟开始的时间，单位是秒
		 */
		delay: {
			type: Number,
			default: 0
		},
		// options
		/**
		 * @description 起始值，即动画开始前显示的数值
		 */
		startVal: {
			type: Number,
			default: 0
		},
		/**
		 * @description 保留几位小数
		 */
		decimals: {
			type: Number,
			default: 0
		},
		/**
		 * @description 动画持续的时间，单位是秒
		 */
		duration: {
			type: Number,
			default: 5
		},
		/**
		 * @description 是否使用分组，分组后每三位会用一个符号分隔
		 */
		usegroup: {
			type: Boolean,
			default: true
		},
		/**
		 * @description 是否禁用easing动画效果
		 */
		uneasing: {
			type: Boolean,
			default: false
		},
		/**
		 * @description 用于分组(usegroup)的符号
		 */
		separator: {
			type: String,
			default: ','
		},
		/**
		 * @description 分隔整数和小数的符号，默认是小数点
		 */
		decimal: {
			type: String,
			default: '.'
		},
		// simplify
		/**
		 * @description 是否简化显示，设为true后会使用unit单位来做相关省略
		 */
		simplify: {
			type: Boolean,
			default: false
		},
		/**
		 * @description 自定义单位，如[3, 'K+'], [6, 'M+']即大于3位数小于6位数的用k+来做省略
		 *              1000即显示为1K+
		 */
		unit: {
			type: Array,
			default () {
				return [[3, 'K+'], [6, 'M+'], [9, 'B+']]
			}
		},
		countClass: {
			type: String,
			default: ''
		},
		unitClass: {
			type: String,
			default: ''
		}
	},
	data () {
		return {
			options: {
				startVal: this.startVal, // number to start at (0)
				decimalPlaces: this.decimals, // number of decimal places (0)
				duration: this.duration, // animation duration in seconds (2)
				useGrouping: this.usegroup, // example: 1,000 vs 1000 (true)
				useEasing: !this.uneasing, // ease animation (true)
				smartEasingThreshold: 999, // smooth easing for large numbers above this if useEasing (999)
				smartEasingAmount: 333, // amount to be eased for numbers above threshold (333)
				separator: this.separator, // grouping separator (',')
				decimal: this.decimal, // decimal ('.')
				// easingFn: easing function for animation (easeOutExpo)
				// easingFn: (t: number, b: number, c: number, d: number) => number;
				// formattingFn: (n: number) => string; // this function formats result
				formattingFn: this.getValue,
				prefix: '', // text prepended to result
				suffix: ''// text appended to result
				// numerals: string[]; // numeral glyph substitution
			},
			unitText: ''
		}
	},
	methods: {
		// 完成
		onReady: function(instance, CountUp) {
			// const that = this;
			// instance.update(that.endVal + 1000);
		},
		getHandleVal (val, len) {
			return {
				endVal: parseInt(val / Math.pow(10, this.unit[len - 1][0])),
				unitText: this.unit[len - 1][1]
			}
		},
		transformValue (val) {
			const len = this.unit.length
			let res = {
				endVal: 0,
				unitText: ''
			}
			if (val < Math.pow(10, this.unit[0][0])) res.endVal = val
			else {
				for (let i = 1; i < len; i++) {
				if (val >= Math.pow(10, this.unit[i - 1][0]) && val < Math.pow(10, this.unit[i][0])) res = this.getHandleVal(val, i)
				}
			}
			if (val > Math.pow(10, this.unit[len - 1][0])) res = this.getHandleVal(val, len)
			return res
		},
		getValue (val) {
			let res = 0
			if (this.simplify) {
				const { endVal, unitText } = this.transformValue(val)
				this.unitText = unitText
				res = endVal + '<i class="' + this.unitClass + '">' + unitText + '</i>'
			} else {
				res = val
			}
			return res
		}
	}
}
</script>